package SunStarUtils;

import java.util.Hashtable;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.view.Gravity;
import android.view.View.MeasureSpec;
import android.view.ViewGroup.LayoutParams;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;

/**
 * @author Ryan Tang
 *
 */
public final class QRCodeHandler {
	private static final int BLACK = 0xff000000;
	
	public static Bitmap createQRCode(String str,int widthAndHeight){
		try {
			// 锟叫讹拷URL锟较凤拷锟斤拷
			if (str == null || "".equals(str) || str.length() < 1) {
				return null;
			}
			Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();
	        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
	        // 图锟斤拷锟斤拷锟斤拷转锟斤拷锟斤拷使锟斤拷锟剿撅拷锟斤拷转锟斤拷
			BitMatrix matrix = new MultiFormatWriter().encode(str,
					BarcodeFormat.QR_CODE, widthAndHeight, widthAndHeight);
			int width = matrix.getWidth();
			int height = matrix.getHeight();
			int[] pixels = new int[width * height];
			// 锟斤拷锟斤拷锟斤拷锟斤按锟秸讹拷维锟斤拷锟斤拷惴拷锟斤拷锟斤拷锟斤拷锟缴讹拷维锟斤拷锟酵计拷锟�
			// 锟斤拷锟斤拷for循锟斤拷锟斤拷图片锟斤拷锟斤拷扫锟斤拷慕锟斤拷
			for (int y = 0; y < height; y++) {
				for (int x = 0; x < width; x++) {
					if (matrix.get(x, y)) {
						pixels[y * width + x] = BLACK;
					}
				}
			}
			// 锟斤拷锟缴讹拷维锟斤拷图片锟侥革拷式锟斤拷使锟斤拷ARGB_8888
			Bitmap bitmap = Bitmap.createBitmap(width, height,
					Config.ARGB_8888);
			bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
			return bitmap;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}


	/**
	 * 锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷
	 *
	 * @param context
	 * @param contents
	 *            锟斤拷要锟斤拷锟缴碉拷锟斤拷锟斤拷
	 * @param desiredWidth
	 *            锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷目锟斤拷
	 * @param desiredHeight
	 *            锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷母叨锟�
	 * @param displayCode
	 *            锟角凤拷锟斤拷锟斤拷锟斤拷锟斤拷锟铰凤拷锟斤拷示锟斤拷锟斤拷
	 * @return
	 */
	public static Bitmap creatBarcode(Context context, String contents,int desiredWidth, int desiredHeight, boolean displayCode) {
		try {
			Bitmap ruseltBitmap = null;
			/**
			 * 图片锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟侥空白的匡拷锟�
			 */
			int marginW = 20;
			/**
			 * 锟斤拷锟斤拷锟斤拷谋锟斤拷锟斤拷锟斤拷锟�
			 */
			BarcodeFormat barcodeFormat = BarcodeFormat.CODE_128;

			if (displayCode) {
				Bitmap barcodeBitmap = encodeAsBitmap(contents, barcodeFormat,
						desiredWidth, desiredHeight);
				Bitmap codeBitmap = creatCodeBitmap(contents, desiredWidth + 2
						* marginW, desiredHeight, context);
				ruseltBitmap = mixtureBitmap(barcodeBitmap, codeBitmap, new PointF(
						0, desiredHeight));
			} else {
				ruseltBitmap = encodeAsBitmap(contents, barcodeFormat,
						desiredWidth, desiredHeight);
			}

			return ruseltBitmap;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟紹itmap
	 *
	 * @param contents
	 *            锟斤拷要锟斤拷锟缴碉拷锟斤拷锟斤拷
	 * @param format
	 *            锟斤拷锟斤拷锟绞�
	 * @param desiredWidth
	 * @param desiredHeight
	 * @return
	 * @throws WriterException
	 */
	protected static Bitmap encodeAsBitmap(String contents,BarcodeFormat format, int desiredWidth, int desiredHeight) {
		final int WHITE = 0xFFFFFFFF;
		final int BLACK = 0xFF000000;

		MultiFormatWriter writer = new MultiFormatWriter();
		BitMatrix result = null;
		try {
			result = writer.encode(contents, format, desiredWidth,
					desiredHeight, null);
		} catch (WriterException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		int width = result.getWidth();
		int height = result.getHeight();
		int[] pixels = new int[width * height];
		// All are 0, or black, by default
		for (int y = 0; y < height; y++) {
			int offset = y * width;
			for (int x = 0; x < width; x++) {
				pixels[offset + x] = result.get(x, y) ? BLACK : WHITE;
			}
		}

		Bitmap bitmap = Bitmap.createBitmap(width, height,
				Config.ARGB_8888);
		bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
		return bitmap;
	}

	/**
	 * 锟斤拷锟斤拷锟斤拷示锟斤拷锟斤拷锟紹itmap
	 *
	 * @param contents
	 * @param width
	 * @param height
	 * @param context
	 * @return
	 */
	protected static Bitmap creatCodeBitmap(String contents, int width,int height, Context context) {
		TextView tv = new TextView(context);
		LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
				LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
		tv.setLayoutParams(layoutParams);
		tv.setText(contents);
		tv.setHeight(height);
		tv.setGravity(Gravity.CENTER_HORIZONTAL);
		tv.setWidth(width);
		tv.setDrawingCacheEnabled(true);
		tv.setTextColor(Color.BLACK);
		tv.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
				MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
		tv.layout(0, 0, tv.getMeasuredWidth(), tv.getMeasuredHeight());

		tv.buildDrawingCache();
		Bitmap bitmapCode = tv.getDrawingCache();
		return bitmapCode;
	}

	/**
	 * 锟斤拷锟斤拷锟斤拷Bitmap锟较诧拷锟斤拷一锟斤拷
	 *
	 * @param first
	 * @param second
	 * @param fromPoint
	 *            锟节讹拷锟斤拷Bitmap锟斤拷始锟斤拷锟狡碉拷锟斤拷始位锟矫ｏ拷锟斤拷锟斤拷诘锟揭伙拷锟紹itmap锟斤拷
	 * @return
	 */
	protected static Bitmap mixtureBitmap(Bitmap first, Bitmap second,PointF fromPoint) {
		if (first == null || second == null || fromPoint == null) {
			return null;
		}
		int marginW = 20;
		Bitmap newBitmap = Bitmap.createBitmap(
				first.getWidth() + second.getWidth() + marginW,
				first.getHeight() + second.getHeight(), Config.ARGB_4444);
		Canvas cv = new Canvas(newBitmap);
		cv.drawBitmap(first, marginW, 0, null);
		cv.drawBitmap(second, fromPoint.x, fromPoint.y, null);
		cv.save(Canvas.ALL_SAVE_FLAG);
		cv.restore();

		return newBitmap;
	}

	/**
	 * 生成图片,并添加logo
	 * @param text
	 * @param w
	 * @param h
	 * @param logo
	 * @return
	 */
	public static  Bitmap createImage(String text,int w,int h,Bitmap logo) {
		try {
			Bitmap scaleLogo = getScaleLogo(logo,w,h);
			int offsetX = 0;
			int offsetY = 0;
			if(scaleLogo != null){
				offsetX = (w - scaleLogo.getWidth())/2;
				offsetY = (h - scaleLogo.getHeight())/2;
			}
			Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();
			hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
			BitMatrix bitMatrix = new QRCodeWriter().encode(text,
					BarcodeFormat.QR_CODE, w, h, hints);
			int[] pixels = new int[w * h];
			for (int y = 0; y < h; y++) {
				for (int x = 0; x < w; x++) {
					//判断是否在logo图片中
					if(offsetX != 0 && offsetY != 0 && x >= offsetX && x < offsetX+scaleLogo.getWidth() && y>= offsetY && y < offsetY+scaleLogo.getHeight()){
						int pixel = scaleLogo.getPixel(x-offsetX,y-offsetY);
						//如果logo像素是透明则写入二维码信息
						if(pixel == 0){
							if(bitMatrix.get(x, y)){
								pixel = 0xff000000;
							}else{
								pixel = 0xffffffff;
							}
						}
						pixels[y * w + x] = pixel;

					}else{
						if (bitMatrix.get(x, y)) {
							pixels[y * w + x] = 0xff000000;
						} else {
							pixels[y * w + x] = 0xffffffff;
						}
					}
				}
			}
			Bitmap bitmap = Bitmap.createBitmap(w, h,
					Bitmap.Config.ARGB_8888);
			bitmap.setPixels(pixels, 0, w, 0, 0, w, h);
			return bitmap;

		} catch (WriterException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 缩放logo到二维码的1/5
	 * @param logo
	 * @param w
	 * @param h
	 * @return
	 */
	private static Bitmap getScaleLogo(Bitmap logo,int w,int h){
		if(logo == null)return null;
		Matrix matrix = new Matrix();
		float scaleFactor = Math.min(w * 1.0f / 5 / logo.getWidth(), h * 1.0f / 5 / logo.getHeight());
		matrix.postScale(scaleFactor,scaleFactor);
		Bitmap result = Bitmap.createBitmap(logo, 0, 0, logo.getWidth(), logo.getHeight(), matrix, true);
		return result;
	}

}
